/***********************************************************************************
 * 文件名： config.h
 * 作者： 刘言
 * 版本： 3.0
 * 说明：
 * 		OkBoot的配置文件。
 * 修改记录：
 *      20210119 V3.0：
 * HJM加密算法改为静态密钥的方式，需要在编译OkBoot时在配置文件中定义密钥，然后生成升级包时输入这个密钥。
 * 求和校验算法改为按4字节求和，取结果的最低4字节作为校验码，4字节数据按照小端排列计算。
 * 接收校验时，支持单独开启或者关闭长度检查，之前只能开启。关闭此开关可以进一步节省代码量。
***********************************************************************************/
#ifndef _CONFIG_H_
#define _CONFIG_H_

/*********************************************************************************************
需要引用的头文件
*********************************************************************************************/

#include "hard_wire.h"

/*********************************************************************************************
工作模式设置
    优先升级模式或者优先跳转模式。
    优先升级模式：启动后先等待升级命令，等待超时后尝试跳转。
    优先跳转模式：启动后先尝试跳转，如果APP错误无法跳转则等待升级命令。注意：此模式如果APP有问题但又能
成功跳转执行，将可能会永远无法升级（重刷固件），即没有外部强制复位重刷固件的可能性了。
*********************************************************************************************/

#define WORK_MODE               0               // 0-优先升级；1-优先跳转

/*********************************************************************************************
APP的一些信息设置
*********************************************************************************************/

#define APP_BASE_ADDR           0x00000800      // 默认的APP起始地址,必须是页首地址（将来计划支持通过通信接口设置）
#define APP_FLAG_ADDR           (APP_BASE_ADDR + 0x00002400)      // 检测是否有APP的地址（标记的地址），仅支持页首地址（FLASH_PAGE_SIZE的整数倍）
#define APP_FLAG_DATA           0XAA55A5A5      // 该地址的标记数据 (32bits)

/*********************************************************************************************
接收超时设置
    优先升级模式下，超时后跳转到APP。
*********************************************************************************************/

#define RECIVE_BYTE_TIMEOUT		0X00040000		// 接收一个字节数据的超时时间计数值 (4MHz M0+ 0x10000 = 120ms)

/*********************************************************************************************
HJM算法加密设置（私有加密算法）
    启用后代表接收到的数据已经被自定义算法加密了，本程序将会对其进行解密后再写入到FLASH。
    可设置一个 自定义算法加密起始地址 ，这样前面一段数据不加密，因为前面一段数据有一些固定字节，不加密可
以提高安全性，仅支持设置页首地址（FLASH_PAGE_SIZE的整数倍）。
*********************************************************************************************/

#define USE_HJM_ENCRYPT         1               // 1：使用HJM算法加密，0：不使用
#define HJM_KEY                 0X030201
#define ENCRYPT_START_ADDR      (APP_BASE_ADDR + FLASH_PAGE_SIZE * 2) // HJM算法加密起始地址，在此之后的数据是加密的，需要解密。

/*********************************************************************************************
AES加密设置
    启用后代表收到的数据已经被AES加密算法加密了，本程序将会对其进行解密后再写入到FLASH。建议有硬件AES
外设的MCU开启。
    注意：如果同时启用了自定义算法加密，本程序会固定先用AES算法解密，然后再用自定义加密算法解密。这意
味着 【固件文件必须先用自定义算法加密然后再用AES加密】。
    可设置一个 AES算法加密起始地址 ，这样前面一段数据不加密，因为前面一段数据有一些固定字节，不加密可
以提高安全性，仅支持设置页首地址（FLASH_PAGE_SIZE的整数倍）。
*********************************************************************************************/

#define USE_AES                 1               // 1: 启用AES加密，0: 不启用。若启用将会进行解密操作后写入FLASH
#define AES_KEY                 {0X00,0X01,0X02,0X03,0X04,0X05,0X06,0X07,0X08,0X09,0X0A,0X0B,0X0C,0X0D,0X0E,0X0F}
#define AES_START_ADDR          (APP_BASE_ADDR + FLASH_PAGE_SIZE * 3)

/*********************************************************************************************
校验设置
    建议启用 每次校验 ，这样每次上电启动后，在跳转到APP之前都会进行完整性验证，通过后才跳转到APP。启用
每次校验必须在 (APP_FLAG_ADDR + 4) 地址保存APP数据总长度（u32数据类型），以便提供给本BootLoader读取。
注意：你必须设置一个合理的 APP_LEN_MAX ，这个值限定了APP数据长度的最大值，避免从FLASH读取到一个过大的
值导致长时间无响应或者寻址错误。
注意：如果校验错误会重复运行BootLoader程序，每当接收超时后都会再次计算校验，但是在计算校验时不会进行UA
RT接收。这意味着，如果校验是错误的，UART将有一小段时间（取决于校验计算的速度）无法回应上位机的指令。适
当 增加接收超时时间 或者 提高运算速度 可以改善这一情况。
    可选启用 接收校验 ，这样在接收并写完所有的APP数据后，会校验其完整性，并返回上位机校验结果。这种校验
方式不会有UART无响应的情况发生，但是你要确保APP在运行的过程中不会有任何形式的指令数据损坏发生。
    必须设置一个校验公式，0：按4字节累加，1：CRC32。
    #############  在升级包APP数据的最后4个字节需要存放校验码  #################。
*********************************************************************************************/

#define USE_PER_TIMES_VERIFY            0               // 1: 启用每次校验，0: 不启用。
#define USE_RECEIVE_VERIFY              1               // 1: 使用接收校验，0：不使用
    #define USE_LENGTH_CHECK                1               // 1：启用长度检查，0: 不启用。
#define APP_LEN_MAX                     (512*1024)       // APP数据总长度可能的最大值
#define VERIFY_FORMULA                  1               // 校验公式，0：按4字节累加，1：CRC32

/*********************************************************************************************
升级接口相关的设置
    多个通信端口时，本程序发送0X7F后，将会锁定第一个发来0XAA的端口进行后续的数据接收，如果锁定的端口后
续不再发来数据将会超时。但是本程序返回的回应会依次从每个端口发送出去，这样便于通过其它端口监视工作状态。
    确保所有开启的端口都不可以快速的发送0XAA，这样会让BootLoader一直处于接收数据状态而不超时退出。
*********************************************************************************************/

#define PORT_NUM                2           // 通信端口数量 1~4
#define Port0                   Uart0       // 端口0 具体的外设
#define Port1                   Uart1       // 端口1 具体的外设
#define Port2                   Lpuart0     // 端口3 具体的外设
#define Port3                   Lpuart1     // 端口4 具体的外设

//#define UART_BAUD_RATE          9600          // 串口驱动不一定调用了这个宏，具体波特率参见串口驱动

/*********************************************************************************************
引用的特殊API设置
    有一些API，不同的MCU可能有不同的参数或者名称（当然你最好把他们设计成相同），或者对于有一些MCU不需要
调用某一些初始化函数，可以在这里将其设置为空定义。
    用户需要添加自定义的初始化和反初始化函数也可以在这里定义。
*********************************************************************************************/

#define FLASH_INIT                                  // Flash初始化，如果不需要初始化留空即可
#define USER_INIT     {GPIO_DIR_OUTPUT(GPIO_PORT_B, 7);M0P_GPIO->PBOUT = 0;UART0_PIN_INIT;UART1_PIN_INIT;}      // 需要添加的用户初始化代码
#define USER_DEINIT                 // 用户反初始化，跳转到APP之前执行

// 检查端口，在发送前执行，确定端口OK后跳出，如果可以肯定端口一直OK，可以留空。
#define CHECK_PORT   

// 回应前等待。某些场景下，收到一包数据后需要稍等一会儿再发送回应数据包，如果不需要可以留空。
#define WAIT_BEFORE_RESPONSE 

#endif


